package sample.ui

import android.Manifest
import android.accessibilityservice.AccessibilityServiceInfo
import android.annotation.SuppressLint
import android.app.Activity
import android.content.Context
import android.content.Intent
import android.media.projection.MediaProjection
import android.media.projection.MediaProjectionManager
import android.net.Uri
import android.os.PowerManager
import android.provider.Settings
import android.view.accessibility.AccessibilityManager
import androidx.lifecycle.MutableLiveData
import android.content.ClipboardManagerService
import kotlinx.coroutines.script.tes.appContext
import kotlinx.coroutines.script.tes.requirePermission
import kotlinx.coroutines.script.tes.runOnUIThread
import com.hjq.permissions.XXPermissions
import kotlinx.coroutines.suspendCancellableCoroutine
import kotlin.coroutines.resume


object Permissions {
    private var cc: Int? = null // 截屏权限
    private var cd: Intent? = null
    private var mp: MediaProjection? = null
    private var batteryHasRequired: Boolean? = null
    val statusUpdated = MutableLiveData<Any?>() // 无障碍权限是否开启. 等同于无障碍服务是否开启

    val isAccessibilityPermissionOpened: Boolean
        get() {
            val accessibilityManager =
                appContext.getSystemService(Context.ACCESSIBILITY_SERVICE) as AccessibilityManager
            val accessibilityServices: List<AccessibilityServiceInfo> =
                accessibilityManager.getEnabledAccessibilityServiceList(AccessibilityServiceInfo.FEEDBACK_GENERIC)
            val hasInList = accessibilityServices.any { it.id.contains(appContext.packageName) }
            return hasInList || ClipboardManagerService.ins != null
//            return true
        }

    val isCaptureAbilityEnable: Boolean
        get() = (cd != null && cc != null) || mp != null

    val isAlertWindowPermissionOpened: Boolean
        get() = XXPermissions.isGrantedPermissions(appContext, Manifest.permission.SYSTEM_ALERT_WINDOW)

    val isIgnoringBatteryOptimizations: Boolean
        get() {
            val powerManager =
                appContext.getSystemService(Context.POWER_SERVICE) as PowerManager
            return powerManager.isIgnoringBatteryOptimizations(appContext.packageName) || batteryHasRequired == true
        }

    val isCDKeyActivating: Boolean
        get() = Properties.ckV2Info?.value?.isNotEmpty() == true // Keys.isUsingCDKeyInfoActivating == 0

    fun updateCDKeyActivating() {
        notifyPermissionStatusUpdated()
    }

    fun requireAlertWindowPermission(context: Activity) {
        context.requirePermission(listOf(Manifest.permission.SYSTEM_ALERT_WINDOW)) {
            notifyPermissionStatusUpdated()
        }
    }

    fun requireAccessibilityPermission(context: Activity) {
        context.startActivity(Intent(Settings.ACTION_ACCESSIBILITY_SETTINGS))
    }

    @SuppressLint("BatteryLife")
    fun requireIgnoreBatteryOptimization(context: Activity) {
        batteryHasRequired = true
        notifyPermissionStatusUpdated()

        val intent = Intent(Settings.ACTION_REQUEST_IGNORE_BATTERY_OPTIMIZATIONS)
        intent.data = Uri.parse("package:${context.packageName}")
        context.startActivity(intent)
    }

    fun requireCaptureScreenPermission(context: Activity) {
        RequireCaptureActivity.require(context) { resultCode, data ->
            // printLog { "Permissions $this save params $resultCode $data" }
            cc = resultCode
            cd = data
            notifyPermissionStatusUpdated()
        }
    }

    suspend fun requireMediaProjection(context: Context): MediaProjection? {
        // printLog { "Permissions $this use params $cc $cd" }
        val captureCode = cc
        val captureData = cd
        if (captureCode != null && captureData != null) {
            val mediaProjectionManager =
                context.getSystemService(Context.MEDIA_PROJECTION_SERVICE) as MediaProjectionManager
            val mediaProjection = mediaProjectionManager.getMediaProjection(captureCode, captureData)
            cc = null
            cd = null
            mp = mediaProjection
            return mediaProjection
        }
        return suspendCancellableCoroutine { continuation ->
            RequireCaptureActivity.require(context) { resultCode, data ->
                val mediaProjectionManager =
                    context.getSystemService(Context.MEDIA_PROJECTION_SERVICE) as MediaProjectionManager
                val mediaProjection = mediaProjectionManager.getMediaProjection(resultCode, data)
                mp = mediaProjection

                continuation.resume(mediaProjection)
            }
        }
    }

    fun releaseMediaProjection() {
        cc = null
        cd = null
        mp = null
        notifyPermissionStatusUpdated()
    }

    private fun notifyPermissionStatusUpdated() = runOnUIThread {
        statusUpdated.value = Any()
        statusUpdated.value = null
    }
    fun notifyHomeUIUpdate() {  notifyPermissionStatusUpdated()  }
}